package com.hyt.it.ogt.ykcj.service.exam.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.it.ogt.ykcj.common.enums.ExamFormEnums;
import com.hyt.it.ogt.ykcj.common.exception.CustomException;
import com.hyt.it.ogt.ykcj.common.utils.bean.BeanUtils;
import com.hyt.it.ogt.ykcj.domain.exam.ExamInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamStemInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamSubjectInfo;
import com.hyt.it.ogt.ykcj.domain.exam.ExamSubjectNameConfig;
import com.hyt.it.ogt.ykcj.domain.grade.EnterpriseExamineeInfo;
import com.hyt.it.ogt.ykcj.domain.grade.EnterpriseExamineeSubjectGrade;
import com.hyt.it.ogt.ykcj.domain.vo.ExamSubjectVo;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamStemInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.exam.ExamSubjectNameConfigMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.EnterpriseExamineeInfoMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.EnterpriseExamineeSubjectGradeMapper;
import com.hyt.it.ogt.ykcj.mapper.grade.ServantExamineeInfoMapper;
import com.hyt.it.ogt.ykcj.service.exam.IEnterpriseExamScoreLineSettingService;
import com.hyt.it.ogt.ykcj.service.exam.IExamSubjectInfoService;
import com.hyt.loginfo.service.IBaseLoginService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 考试科目信息Service业务层处理
 *
 * @author admin
 * @date 2021-06-18
 */
@Service
public class ExamSubjectInfoServiceImpl extends BaseServiceImpl<ExamSubjectInfoMapper, ExamSubjectInfo> implements IExamSubjectInfoService {


    @Autowired
    private ExamSubjectInfoMapper examSubjectInfoMapper;

    @Autowired
    private ExamInfoMapper examInfoMapper;

    @Autowired
    private ExamStemInfoMapper examStemInfoMapper;

    @Autowired
    private ServantExamineeInfoMapper servantExamineeInfoMapper;

    @Autowired
    private ExamSubjectNameConfigMapper examSubjectNameConfigMapper;

    @Autowired
    private EnterpriseExamineeSubjectGradeMapper enterpriseExamineeSubjectGradeMapper;

    @Autowired
    private IEnterpriseExamScoreLineSettingService iEnterpriseExamScoreLineSettingService;

    @Autowired
    private EnterpriseExamineeInfoMapper enterpriseExamineeInfoMapper;

    @Autowired
    private IBaseLoginService iBaseLoginService;

    /**
     * 查询考试科目信息
     *
     * @param id 考试科目信息ID
     * @return 考试科目信息
     */
    @Override
    public ExamSubjectInfo selectExamSubjectInfoById(String id) {
        return examSubjectInfoMapper.selectExamSubjectInfoById(id);
    }

    /**
     * 查询考试科目信息列表
     *
     * @param examSubjectInfo 考试科目信息
     * @return 考试科目信息
     */
    @Override
    public List<ExamSubjectInfo> selectExamSubjectInfoList(ExamSubjectInfo examSubjectInfo) {
        return examSubjectInfoMapper.selectExamSubjectInfoList(examSubjectInfo);
    }

    /**
     * 查询考试科目是否已存在
     *
     * @param @param  examInfoId
     * @param @param  examSubjectNameId
     * @param @return
     */
    public int checkSubJectInfoIsExist(String examInfoId, String examSubjectNameId) {
        Map<String, Object> parms = new HashedMap<>();
        parms.put("examInfoId", examInfoId);
        parms.put("examSubjectNameId", examSubjectNameId);
        return examSubjectInfoMapper.findSubJectInfoIsExist(parms);
    }

    @Override
    public List<ExamSubjectVo> selectExamSubjectInfoByExamId(String examId) {
        List<ExamSubjectVo> examSubjectVos = examSubjectInfoMapper.selectExamSubjectInfoByExamId(examId);
        if (CollectionUtils.isEmpty(examSubjectVos)) {
            return examSubjectVos;
        }
        for (ExamSubjectVo vo : examSubjectVos) {
            ExamStemInfo examStemInfo = new ExamStemInfo();
            examStemInfo.setSubjectId(vo.getSubjectId());
            List<ExamStemInfo> examStemInfos = examStemInfoMapper.selectExamStemInfoList(examStemInfo);
            vo.setExamStemInfo(examStemInfos);
        }

        return examSubjectVos;
    }

    /**
     * 获取设置分数线表头科目
     *
     * @param examId 考试ID
     * @return 结果
     */
    @Override
    public List<Map<String, String>> getSettingScoreLineSubjectName(String examId) {
        List<Map<String, String>> resultList = new ArrayList<>();
        List<Map<String, String>> list = examSubjectInfoMapper.selectSettingScoreLineSubjectName(examId, "1");
        if (list.size() > 0) {
            Map<String, String> compositeSubject = new HashMap<>();
            for (Map<String, String> map : list) {
                String isComposite = String.valueOf(map.get("isComposite"));
                if ("1".equals(isComposite)) {
                    if (compositeSubject.get("code") == null) {
                        compositeSubject = map;
                    } else {
                        compositeSubject.put("subjectId", compositeSubject.get("subjectId") + "+" + map.get("subjectId"));
                        compositeSubject.put("code", compositeSubject.get("code") + "+" + map.get("code"));
                        compositeSubject.put("name", compositeSubject.get("name") + "+" + map.get("name"));
                        BigDecimal fullMarks1 = new BigDecimal(String.valueOf(compositeSubject.get("fullMarks")));
                        BigDecimal fullMarks2 = new BigDecimal(String.valueOf(map.get("fullMarks")));
                        BigDecimal fullMarks = fullMarks1.add(fullMarks2);
                        compositeSubject.put("fullMarks", fullMarks.toString());
                    }
                }
            }
            resultList.add(compositeSubject);
        }
        resultList.addAll(examSubjectInfoMapper.selectSettingScoreLineSubjectName(examId, "0"));
        return resultList;
    }

    /**
     * 查询考试科目信息列表
     *
     * @param examId 考试ID
     * @return 考试科目信息
     */
    @Override
    public List<ExamSubjectVo> getExamSubjectInfoList(String examId) {
        List<ExamSubjectVo> examSubjectVoList = new ArrayList<>();
        Map<String, Object> params = new HashMap<>();
        params.put("examInfoId", examId);
        List<ExamSubjectInfo> examSubjectInfoList = examSubjectInfoMapper.selectExamSubjectInfoListAllByParms(params);
        ExamSubjectVo subjectVo = new ExamSubjectVo();
        for (ExamSubjectInfo examSubjectInfo : examSubjectInfoList) {
            ExamSubjectVo examSubjectVo = new ExamSubjectVo();
            BeanUtils.copyBeanProp(examSubjectVo, examSubjectInfo);
            examSubjectVo.setSubjectNameCode(examSubjectInfo.getSubjectCode());
            examSubjectVo.setSubjectName(examSubjectInfo.getExamSubjectName());
            ExamStemInfo examStemInfo = new ExamStemInfo();
            examStemInfo.setSubjectId(examSubjectInfo.getId());
            params = new HashMap<>();
            params.put("orderBy", "sort");
            examStemInfo.setParams(params);
            examSubjectVo.setExamStemInfo(examStemInfoMapper.selectExamStemInfoList(examStemInfo));
            examSubjectVoList.add(examSubjectVo);
            if ("1".equals(examSubjectInfo.getIsComposite())) {
                if (null == subjectVo.getId()) {
                    subjectVo.setId(examSubjectInfo.getId());
                    subjectVo.setSubjectName(examSubjectInfo.getExamSubjectName());
                    subjectVo.setIsComposite(examSubjectInfo.getIsComposite());
                } else {
                    subjectVo.setId(subjectVo.getId() + "+" + examSubjectInfo.getId());
                    subjectVo.setSubjectName(subjectVo.getSubjectName() + "+" + examSubjectInfo.getExamSubjectName());
                }
            }
        }
        if (StringUtils.isNotEmpty(subjectVo.getId()) && subjectVo.getId().indexOf("+") != -1) {
            examSubjectVoList.add(subjectVo);
        }

        return examSubjectVoList;
    }

    @Override
    public List<ExamSubjectVo> selectExamSubjectInfoByExamType(String examType) {
        return examSubjectInfoMapper.selectExamSubjectInfoRecent(examType);
    }

    @Override
    public List<ExamSubjectVo> selectExamSubjectListByIds(String[] ids) {
        return examSubjectInfoMapper.selectExamSubjectListByIds(ids);
    }

    @Override
    public List<ExamSubjectVo> selectExamSubjectListByExamIds(String[] ids) {
        return examSubjectInfoMapper.selectExamSubjectListByExamIds(ids);
    }


    @Override
    public void deleteEnterpriseSubjectById(String subjectId) {
        ExamSubjectInfo examSubjectInfo = examSubjectInfoMapper.selectExamSubjectInfoById(subjectId);
        if (null == examSubjectInfo) {
            throw new CustomException("科目不存在!");
        }

        // 判断是否归档
        ExamInfo examInfo = examInfoMapper.selectExamInfoById(examSubjectInfo.getExamInfoId());
        if (StringUtils.isNotEmpty(examInfo.getOrigin()) && "1".equals(examInfo.getOrigin())) {
            throw new CustomException("所选考试下存在云考试同步数据，不允许删除!");
        }

        // 判断科目数量
        if (ExamFormEnums.FORM_EXAM_GROUP.getCode().equals(examInfo.getExamForm())) {
            List<ExamSubjectVo> examSubjectVos = examSubjectInfoMapper.selectExamSubjectInfoByExamId(examInfo.getId());
            if (examSubjectVos.size() <= 1) {
                throw new CustomException("考试组科目不能为空，不允许删除!");
            }
        }

        Integer count = enterpriseExamineeSubjectGradeMapper.countArchivedExamineeSubjectGrade(examSubjectInfo.getExamInfoId().split(","), null);
        if (null != count && count.intValue() > 0) {
            throw new CustomException("所选考试下存在已归档考生成绩数据，不允许删除!");
        }

        List<EnterpriseExamineeSubjectGrade> enterpriseExamineeSubjectGradeList = enterpriseExamineeSubjectGradeMapper.selectGradeByExamIdAndSubjectId(subjectId);
        if (CollectionUtils.isNotEmpty(enterpriseExamineeSubjectGradeList)) {
            List<String> examieeIdList = enterpriseExamineeSubjectGradeList.stream().map(EnterpriseExamineeSubjectGrade::getExamineeId).collect(Collectors.toList());
            // 删除考生数据
            enterpriseExamineeInfoMapper.deleteEnterpriseExamineeInfoByIds(examieeIdList.stream().toArray(String[]::new));
        }
        // 删除科目名
        examSubjectNameConfigMapper.deleteExamSubjectNameConfigById(examSubjectInfo.getExamSubjectNameId());
        // 删除科目
        examSubjectInfoMapper.deleteExamSubjectInfoById(subjectId);
        // 删除题干
        examStemInfoMapper.deleteExamStemInfoBySubjectId(subjectId);
        // 删除分数线设置
        if (iEnterpriseExamScoreLineSettingService.deleteScoreLineBySubjectId(subjectId)) {
            // 同步成绩通过状态
            iEnterpriseExamScoreLineSettingService.gradeStatusSync(examSubjectInfo.getExamInfoId(), null);
        }
        // 删除科目成绩
        enterpriseExamineeSubjectGradeMapper.deleteEnterpriseExamineeSubjectGradeByExamId(examSubjectInfo.getExamInfoId(), subjectId);
    }


    @Override
    public List<ExamSubjectVo> selecSubjectList(String examId) {
        return examSubjectInfoMapper.selecSubjectList(examId);
    }

    @Override
    public List<ExamSubjectVo> selectExamSubjectListByExamIds(List<String> examIds) {
        return examSubjectInfoMapper.selectExamSubjectListByExamIds(examIds.toArray(new String[examIds.size()]));
    }

    @Override
    public void examineeRepeatCheck(String subjectIds) {
        String[] subjectIdArr = subjectIds.split(",");
        if(subjectIdArr.length < 2){
            return;
        }
        List<String> checkList = new ArrayList<>();
        for (String subjectId : subjectIdArr) {
            List<EnterpriseExamineeSubjectGrade> enterpriseExamineeSubjectGradeList = enterpriseExamineeSubjectGradeMapper.selectGradeByExamIdAndSubjectId(subjectId);
            if (CollectionUtils.isEmpty(enterpriseExamineeSubjectGradeList)) {
                continue;
            }
            List<String> examnieeIds = enterpriseExamineeSubjectGradeList.stream().map(EnterpriseExamineeSubjectGrade::getExamineeId).distinct().collect(Collectors.toList());
            List<EnterpriseExamineeInfo> enterpriseExamineeInfoList = enterpriseExamineeInfoMapper.selectEnterpriseExamineeInfoByIds(examnieeIds);
            for(EnterpriseExamineeInfo enterpriseExamineeInfo : enterpriseExamineeInfoList){
                if(StrUtil.isEmpty(enterpriseExamineeInfo.getIdcard())){
                    // 为空就不校验了
                    continue;
                }
                String key = enterpriseExamineeInfo.getName() + enterpriseExamineeInfo.getIdcard();
                if(!checkList.contains(key)){
                    checkList.add(key);
                }else{
                    throw new CustomException("同一个考生在多个科目中有成绩，不允许进行科目合并!");
                }
            }
        }

    }


    @Override
    public List<ExamSubjectInfo> getExamSubjectInfos(String examId,String subjectId){
        QueryWrapper<ExamSubjectInfo> queryWrapper = new QueryWrapper<>();
        if(StringUtils.isEmpty(subjectId)){// 总成绩表
            queryWrapper.lambda().eq(ExamSubjectInfo::getExamInfoId, examId);
        }else {// 科目成绩表
            queryWrapper.lambda().eq(ExamSubjectInfo::getExamInfoId, examId).eq(ExamSubjectInfo::getId,subjectId);
        }
        List<ExamSubjectInfo>  subjectList = examSubjectInfoMapper.selectList(queryWrapper);
        if(CollectionUtils.isEmpty(subjectList)){
            return  Collections.EMPTY_LIST;
        }
        List<String> subjectIds = subjectList.stream().map(e->e.getId()).collect(Collectors.toList());
        QueryWrapper<ExamStemInfo> stemQueryWrapper = new QueryWrapper<>();
        stemQueryWrapper.lambda().in(ExamStemInfo::getSubjectId,subjectIds );
        List<ExamStemInfo> examStemInfos = examStemInfoMapper.selectList(stemQueryWrapper);
        Map<String, List<ExamStemInfo>> examStemMap = examStemInfos.stream().collect(Collectors.groupingBy(c -> c.getSubjectId()));

        List<String> configIds = subjectList.stream().map(e->e.getExamSubjectNameId()).collect(Collectors.toList());
        QueryWrapper<ExamSubjectNameConfig> subjectNameConfigQueryWrapper = new QueryWrapper<>();
        subjectNameConfigQueryWrapper.lambda().in(ExamSubjectNameConfig::getId, configIds );
        List<ExamSubjectNameConfig> examSubjectNameConfigs = examSubjectNameConfigMapper.selectList(subjectNameConfigQueryWrapper);
        Map<String,String> nameMap = examSubjectNameConfigs.stream().collect(Collectors.toMap(ExamSubjectNameConfig::getId, ExamSubjectNameConfig::getName,(key1, key2)->key2));


        for (ExamSubjectInfo examSubjectInfo :subjectList) {
            if(MapUtils.isEmpty(nameMap)){
                continue;
            }
            examSubjectInfo.setSubjectName(nameMap.get(examSubjectInfo.getExamSubjectNameId()));
            if(MapUtils.isEmpty(examStemMap) || CollectionUtils.isEmpty(examStemMap.get(examSubjectInfo.getId()))){
                continue;
            }
            examSubjectInfo.setExamStemInfos(examStemMap.get(examSubjectInfo.getId()));

        }
        return  subjectList;
    }

}
